package ua.kiev.tosik.price.modules.search.gui;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.pushingpixels.flamingo.api.common.CommandButtonDisplayState;
import org.pushingpixels.flamingo.api.common.JCommandButton;
import org.pushingpixels.flamingo.api.common.JCommandMenuButton;
import org.pushingpixels.flamingo.api.common.RichTooltip;
import org.pushingpixels.flamingo.api.common.popup.JCommandPopupMenu;
import org.pushingpixels.flamingo.api.common.popup.JPopupPanel;
import org.pushingpixels.flamingo.api.common.popup.PopupPanelCallback;
import org.pushingpixels.substance.api.renderers.SubstanceDefaultListCellRenderer;
import ua.kiev.tosik.price.gui.CenterPanel;
import ua.kiev.tosik.price.gui.helper.AutoCompleteDecorator;
import ua.kiev.tosik.price.gui.tools.IconWrapperResizableIcon;
import ua.kiev.tosik.price.models.Prices;
import ua.kiev.tosik.price.modules.search.conf.FilterConfig;
import ua.kiev.tosik.price.modules.search.conf.IFilter;
import ua.kiev.tosik.price.modules.search.conf.ModuleConfig;
import ua.kiev.tosik.price.modules.search.gui.models.TransferablePricesFlavor;

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.*;
import java.text.DecimalFormat;
import java.util.Vector;

public class MainToolBar {

	private static Logger logger = Logger.getLogger("ua.kiev.tosik.price.modules.search.gui");

	private JToolBar toolBar;
	// private JButton createNewButton;
	private JButton findButton;
	private JButton reloadButton;
	private JButton closeModuleButton;
	private JTextField quickSearch;
    private JTextField percentField;
	private JLabel recordFoundInfo;
	private MainPanel mainPanel;

	private JCommandButton notepadButton;

	// private ActionListener createAction;
	private ActionListener reloadAction;
	private ActionListener findAction;
	private ActionListener closeModuleAction;

	private ModuleConfig config;

	private DecimalFormat df = new DecimalFormat("##,###.##");
	private Notepad notepad;
	private RichTooltip notepadToolTip;

	private JComboBox searchComboBox;
	private JComboBox searchTypeComboBox;
	private DefaultComboBoxModel searchModel;
	private Vector<String> sList = new Vector<String>();

	private FilterConfig filterConfig;

	public MainToolBar(MainPanel mainPanel) {
		this.mainPanel = mainPanel;

		config = ModuleConfig.getInstance();

		toolBar = new JToolBar();
		toolBar.setBorder(BorderFactory.createLineBorder(Color.gray, 1));
		toolBar.setFloatable(false);

		filterConfig = new FilterConfig();

		initActions();
		createButtons(toolBar);

		notepadButton.setTransferHandler(new TransferHandler() {
			@Override
			public boolean canImport(TransferSupport support) {
				return true;
			}

			@Override
			public void exportAsDrag(JComponent comp, InputEvent e, int action) {
				super.exportAsDrag(comp, e, action);
				logger.debug(comp.getClass().getSimpleName());
			}

			@Override
			@SuppressWarnings("unchecked")
			public boolean importData(TransferSupport support) {
				Transferable tr = support.getTransferable();
				DataFlavor[] flavors = tr.getTransferDataFlavors();
				for (DataFlavor flavor : flavors) {
					logger.debug("Possible flavor: " + flavor.getMimeType());
					if (flavor.isFlavorSerializedObjectType()) {
						Vector<Prices> prices = null;
						TransferablePricesFlavor pricesFlavor = null;
						try {
							pricesFlavor = (TransferablePricesFlavor)tr.getTransferData(flavor);
							prices = pricesFlavor.getPrices();
							logger.debug("Drag " + prices.size() + " record(s)");
							int[] rows = pricesFlavor.getRows();
							if ( notepad == null ) {
								notepad = new Notepad();
							}
							notepad.addPrices(prices);
							notepadButton.setText(config.get("search.toolbar.notepad.text") + " ( " + df.format(notepad.getSum()) + " )");
							if ( rows.length > 0 ) {
								refreshTable(rows);
							}
						} catch (Exception e) {
							logger.warn(e.getMessage(), e);
						}
					}
				}
				return true;
			}
		});

	}

	public JToolBar getToolBar() {
		return toolBar;
	}

	public double getPercent() {
		try {
			return Double.valueOf(percentField.getText());
		} catch (Exception e) {
			logger.warn("Non numeric value in Percent Field!");
			return 0;
		}
	}

	private void refreshTable(int[] rows) {
		for ( int row: rows ) {
			int r = mainPanel.getTable().getTable().convertRowIndexToModel(row);
			mainPanel.getTable().getModel().getRow(row).setSelected(true);
		}
		mainPanel.getTable().getModel().fireTableRowsUpdated(rows[0], rows[rows.length-1]);
	}

	private void initActions() {
		reloadAction = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					searchComboBox.setSelectedIndex(-1);
					mainPanel.resetDao();
					mainPanel.loadData();
				} catch (Exception e1) {
					logger.error(e1.getMessage(), e1);
				}
			}
		};
		findAction = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				showSearchForm();
			}
		};
		closeModuleAction = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				closeModule();
			}
		};
	}

	private void showSearchForm() {
		mainPanel.showSearchPanel(true);
	}

	public void setEnable(boolean enable) {
		// quickSearch.setEnabled(enable);
		searchTypeComboBox.setEnabled(enable);
		findButton.setEnabled(enable);
		reloadButton.setEnabled(enable);
		closeModuleButton.setEnabled(enable);
		notepadButton.setEnabled(enable);
		searchComboBox.setEnabled(enable);
		percentField.setEnabled(enable);
	}

	private void createButtons(JToolBar toolBar) {
		findButton = new JButton();
		findButton.addActionListener(findAction);
		reloadButton = new JButton();
		reloadButton.addActionListener(reloadAction);
		closeModuleButton = new JButton();
		closeModuleButton.addActionListener(closeModuleAction);
		notepadButton = new JCommandButton(config.get("search.toolbar.notepad.text"));
		notepadButton.setDisplayState(CommandButtonDisplayState.MEDIUM);
		notepadButton.setCommandButtonKind(JCommandButton.CommandButtonKind.ACTION_AND_POPUP_MAIN_ACTION);
		// notepadButton.setCommandButtonKind(JCommandButton.CommandButtonKind.ACTION_AND_POPUP_MAIN_POPUP);
		notepadButton.setFlat(false);
		notepadButton.setPopupCallback( new NotepadMenu() );

		recordFoundInfo = new JLabel();
		percentField = new JTextField(5);

		toolBar.add(findButton);
		toolBar.add(reloadButton);
		toolBar.addSeparator();
		toolBar.add(closeModuleButton);
		toolBar.addSeparator();
		toolBar.add(notepadButton);
		toolBar.addSeparator();
		toolBar.add(recordFoundInfo);
		toolBar.add(Box.createHorizontalGlue());
		JPanel qsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));

		JLabel percentLabel = new JLabel(new ImageIcon(config.get("search.toolbar.percent.icon")));
		percentField.setText("0");
		percentField.setHorizontalAlignment(SwingConstants.RIGHT);
		percentField.addKeyListener(new KeyListener() {
			@Override
			public void keyTyped(KeyEvent keyEvent) {}
			@Override
			public void keyReleased(KeyEvent keyEvent) {}
			@Override
			public void keyPressed(KeyEvent keyEvent) {
				logger.debug("Init Quick search from Percent Field");
				if (keyEvent.getKeyCode() == KeyEvent.VK_ENTER) {
					if ( percentField.getText().trim().equals("") ) {
						percentField.setText("0");
					}
					mainPanel.resetDao();
					try {
						mainPanel.loadData();
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
					}
				}
			}
		});
		// percentLabel.add(percentField);
		qsPanel.add(percentLabel);
		qsPanel.add(percentField);

		JLabel qsImageLabel = new JLabel(new ImageIcon(config.get("search.toolbar.quickSearch.icon")));
		qsImageLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		qsImageLabel.addMouseListener( new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getButton() == MouseEvent.BUTTON1 ) {
					searchComboBox.setSelectedIndex(-1);
				}
			}
		});
		qsPanel.add(qsImageLabel);

		searchModel = new DefaultComboBoxModel();
		searchComboBox = new JComboBox();
		searchComboBox.setEditable(true);
		searchComboBox.setModel(searchModel);
		searchComboBox.setPreferredSize( new Dimension((int)searchComboBox.getPreferredSize().getWidth()+80, (int)searchComboBox.getPreferredSize().getHeight()));
		searchComboBox.addActionListener( new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if ( "comboBoxEdited".equals(e.getActionCommand()) ) {
					logger.debug("Init quick search action");
					String s = StringUtils.defaultString((String)searchComboBox.getSelectedItem());
					logger.debug("Search string: " + s);
					mainPanel.resetDao();
					try {
						mainPanel.loadData();
					} catch (Exception e1) {
						logger.error(e1.getMessage(), e1);
					}
					if ( !s.equals("") && s.length() >= 3 && !sList.contains(s) ) {
						searchModel.addElement(s);
						sList.add(s);
					}
					// return;
				}
				/*JComboBox cb = (JComboBox)e.getSource();
				String newSelection = (String)cb.getSelectedItem();
				logger.debug(newSelection);*/
			}
		});
		// Use custom class with replace of Backspace action !!!
		AutoCompleteDecorator.decorate(searchComboBox);

		if ( filterConfig.getFilters().size() > 0 ) {
			JLabel filterImageLabel = new JLabel(new ImageIcon(config.get("search.toolbar.filter.icon")));
			searchTypeComboBox = new JComboBox();
			searchTypeComboBox.setRenderer( new FilterListCellRenderer() );
			for ( IFilter filter: filterConfig.getFilters() ) {
				searchTypeComboBox.addItem(filter);
			}
			qsPanel.add(searchComboBox);
			qsPanel.add(filterImageLabel);
			searchTypeComboBox.addActionListener( new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					try {
						String s = StringUtils.defaultString((String)searchComboBox.getSelectedItem());
						if ( !s.equals("") ) {
							mainPanel.loadData();
						}
					} catch (Exception e1) {
						logger.error(e1.getMessage(), e1);
					}
				}
			});
		}

		qsPanel.add(searchTypeComboBox);


//		quickSearch = new JTextField(20);
//		qsPanel.add(quickSearch);
//		quickSearch.addKeyListener(new KeyListener() {
//			public void keyTyped(KeyEvent e) {
//			}
//
//			public void keyPressed(KeyEvent e) {
//			}
//
//			public void keyReleased(KeyEvent e) {
//				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
//					logger.debug("Init quick search action");
//					// quickSearch.setEnabled(false);
//					Prices prices = new Prices();
//					prices.setName(quickSearch.getText());
//					mainPanel.resetDao();
//					try {
//						mainPanel.loadData();
//					} catch (Exception e1) {
//						logger.error(e1.getMessage(), e1);
//					}
//				}
//			}
//		});
		setButtonLabels();
		toolBar.add(qsPanel);
	}

	public Prices getPrices() {
		if ( searchTypeComboBox != null ) {
			IFilter filter = (IFilter)searchTypeComboBox.getSelectedItem();
			filter.setSearchString(StringUtils.defaultString((String)searchComboBox.getSelectedItem()));
			return filter.getPrices();
		} else {
			String s = StringUtils.defaultString((String)searchComboBox.getSelectedItem());
			Prices prices = new Prices();
			prices.setName(s);
			prices.setArticle(s);
			prices.setArticleInternal(s);
			return prices;
		}
	}

	private void setButtonLabels() {
		findButton.setIcon(new ImageIcon(config.get("search.toolbar.find.icon")));
		findButton.setToolTipText(config.get("search.toolbar.find.text"));
		reloadButton.setIcon(new ImageIcon(config.get("search.toolbar.reload.icon")));
		reloadButton.setToolTipText(config.get("search.toolbar.reload.text"));
		closeModuleButton.setToolTipText(config.get("search.toolbar.close.text"));
		closeModuleButton.setIcon(new ImageIcon(config.get("search.toolbar.close.icon")));
		// notepadButton.setText(config.get("search.toolbar.notepad.text"));
		// notepadButton.setIcon((ResizableIcon)new ImageIcon(config.get("search.toolbar.notepad.icon")));
		notepadButton.setIcon( new IconWrapperResizableIcon(new ImageIcon(config.get("search.toolbar.notepad.icon"))) );
		// notepadButton.setExtraText("Some text");
		notepadToolTip = new RichTooltip();
		notepadToolTip.setTitle(config.get("search.toolbar.notepad.text"));
		notepadToolTip.addDescriptionSection(config.get("search.toolbar.notepad.selectedItems.text") + ": 0");
		notepadToolTip.addFooterSection(config.get("search.toolbar.notepad.cost.text") + ": 0");
		// toolTip.addDescriptionSection("Section 2");
		notepadToolTip.setMainImage( new ImageIcon(config.get("search.toolbar.notepad.selectedItems.icon")).getImage() );
		notepadToolTip.setFooterImage( new ImageIcon(config.get("search.toolbar.notepad.cost.icon")).getImage() );
		notepadButton.setPopupRichTooltip(notepadToolTip);
	}

	private void closeModule() {
		CenterPanel.getInstance().closeTab(mainPanel.getModule());
	}

	private class NotepadMenu implements PopupPanelCallback {

		private JCommandMenuButton openNotepad;
		private JCommandMenuButton addSelected;
		private JCommandMenuButton clearSelected;
		private JCommandMenuButton clearNotepad;
		private JCommandMenuButton saveNotepad;

		public NotepadMenu() {
			openNotepad = new JCommandMenuButton(config.get("search.toolbar.notepad.open.text"), new IconWrapperResizableIcon(new ImageIcon(config.get("search.toolbar.notepad.open.icon"))));
			addSelected = new JCommandMenuButton(config.get("search.toolbar.notepad.addSelected.text"), new IconWrapperResizableIcon(new ImageIcon(config.get("search.toolbar.notepad.addSelected.icon"))));
			clearSelected = new JCommandMenuButton(config.get("search.toolbar.notepad.clear.text"), new IconWrapperResizableIcon(new ImageIcon(config.get("search.toolbar.notepad.clear.icon"))));
			clearNotepad = new JCommandMenuButton(config.get("search.toolbar.notepad.clearNotepad.text"), new IconWrapperResizableIcon(new ImageIcon(config.get("search.toolbar.notepad.clearNotepad.icon"))));
			saveNotepad = new JCommandMenuButton(config.get("search.toolbar.notepad.save.text"), new IconWrapperResizableIcon(new ImageIcon(config.get("search.toolbar.notepad.save.icon"))));

			clearNotepad.addActionListener( new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					if ( notepad != null ) {
						notepad.clearPrices();
					}
				}
			});
		}

		@Override
		public JPopupPanel getPopupPanel(JCommandButton jCommandButton) {
			JCommandPopupMenu simpleMenu = new JCommandPopupMenu();
			simpleMenu.addMenuButton(openNotepad);
			simpleMenu.addMenuButton(addSelected);
			simpleMenu.addMenuSeparator();
			simpleMenu.addMenuButton(saveNotepad);
			simpleMenu.addMenuButton(clearSelected);
			simpleMenu.addMenuButton(clearNotepad);
			return simpleMenu;
		}
	}

	private class FilterListCellRenderer extends SubstanceDefaultListCellRenderer {

		@Override
		public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
			JLabel component = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
			IFilter filter = (IFilter)value;
			setText(filter.getName());
			return this;
		}
	}

}
